package com.xxl.job.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoDatabase;
import com.xxl.excel.core.ExcelExportUtil;
import com.xxl.job.admin.dao.DbInfoDao;
import com.xxl.job.admin.service.DbInfoService;
import com.xxl.job.core.biz.model.DbInfo;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.constants.Constants;
import com.xxl.job.core.util.DateUtil;
import com.xxl.job.core.util.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class DbInfoServiceImpl implements DbInfoService {

    @Resource
    private DbInfoDao dbInfoDao;

    /**
     * add dbInfo
     *
     * @param dbInfo
     * @return
     */
    @Override
    public ReturnT<String> add(DbInfo dbInfo) {
        if(dbInfo == null) return ReturnT.FAIL;
        if(StringUtils.isBlank(dbInfo.getName())) return ReturnT.FAIL; //校验数据

        int result = dbInfoDao.save(dbInfo);//保存

        if(result <= 0) return ReturnT.FAIL;//保存失败
        return ReturnT.SUCCESS;
    }

    /**
     * update dbInfo
     *
     * @param dbInfo
     * @return
     */
    @Override
    public ReturnT<String> update(DbInfo dbInfo) {
        if(dbInfo == null || dbInfo.getId() == null) return ReturnT.FAIL;//非空判断

        int result = dbInfoDao.update(dbInfo);//更新

        if(result <= 0) return ReturnT.FAIL;//更新失败
        return ReturnT.SUCCESS;
    }

    /**
     * delete dbInfo
     *
     * @param id
     * @return
     */
    @Override
    public ReturnT<String> remove(Long id) {
        if(id == null) return ReturnT.FAIL;//非空判断

        int result = dbInfoDao.delete(id);//删除

        if(result <= 0) return ReturnT.FAIL;//删除失败
        return ReturnT.SUCCESS;
    }

    /**
     * copy dbInfo
     *
     * @param dbInfo
     * @return
     */
    @Override
    public ReturnT<String> copy(DbInfo dbInfo) {
        if(dbInfo == null || dbInfo.getId() == null) return ReturnT.FAIL;//非空判断

        DbInfo dbInfo1 = dbInfoDao.loadById(dbInfo.getId());//要复制的对象

        if(StringUtils.isNotBlank(dbInfo.getName())) {
            dbInfo1.setName(dbInfo.getName());
        }

        if(StringUtils.isNotBlank(dbInfo.getDbDriver())) {
            dbInfo1.setDbDriver(dbInfo.getDbDriver());
        }

        if(StringUtils.isNotBlank(dbInfo.getDbUrl())) {
            dbInfo1.setDbUrl(dbInfo.getDbUrl());
        }

        if(StringUtils.isNotBlank(dbInfo.getDbPassword())) {
            dbInfo1.setDbPassword(dbInfo.getDbPassword());
        }

        if(StringUtils.isNotBlank(dbInfo.getDbUserName())) {
            dbInfo1.setDbUserName(dbInfo.getDbUserName());
        }

        if(StringUtils.isNotBlank(dbInfo.getDbType())) {
            dbInfo1.setDbType(dbInfo.getDbType());
        }

        int result = dbInfoDao.save(dbInfo1);
        if(result <= 0) return ReturnT.FAIL;

        return ReturnT.SUCCESS;
    }

    /**
     * copy dbInfo
     *
     * @param id
     * @return
     */
    @Override
    public ReturnT<String> copy(Long id) {
        if(id == null) return ReturnT.FAIL;
        DbInfo dbInfo = dbInfoDao.loadById(id);
        if(dbInfo == null) return ReturnT.FAIL;

        dbInfo.setId(null);
        int result = dbInfoDao.save(dbInfo);
        if(result <= 0) return ReturnT.FAIL;

        return ReturnT.SUCCESS;
    }

    /**
     * query dbInfo by id
     *
     * @param id
     * @return
     */
    @Override
    public ReturnT<DbInfo> loadById(long id) {
        DbInfo dbInfo = dbInfoDao.loadById(id);
        if(dbInfo != null) {
            ReturnT<DbInfo> returnT = new ReturnT<>(dbInfo);
            return returnT;
        }
        return new ReturnT<>(ReturnT.FAIL_CODE, "query dbInfo fail");
    }

    /**
     * test dbInfo
     *
     * @param id
     * @return
     */
    @Override
    public ReturnT<String> testDbInfoById(Long id) {
        if(id == null) return ReturnT.FAIL;
        DbInfo dbInfo = dbInfoDao.loadById(id);

        if(StringUtils.isNotBlank(dbInfo.getDbType()) && Constants.DB_TYPE_MONGODB.equals(dbInfo.getDbType())) {
            MongoClient mongoClient = null;
            try {
                //MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(new MongoClient(dbInfo.getDbUrl(), Integer.parseInt(dbInfo.getMongodbPort())), dbInfo.getMongodbDatabase());
                ServerAddress serverAddress = new ServerAddress(dbInfo.getDbUrl(),Integer.parseInt(dbInfo.getMongodbPort()));
                List<ServerAddress> addrs = new ArrayList<>();
                addrs.add(serverAddress);
                //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
                MongoCredential credential = MongoCredential.createScramSha1Credential(dbInfo.getDbUserName(), dbInfo.getMongodbDatabase(), dbInfo.getDbPassword().toCharArray());
                List<MongoCredential> credentials = new ArrayList<>();
                credentials.add(credential);
                //通过连接认证获取MongoDB连接
                mongoClient = new MongoClient(addrs,credentials);
                //连接到数据库
                MongoDatabase mongoDatabase = mongoClient.getDatabase(dbInfo.getMongodbDatabase());
                System.out.println("mongoDatabase.getName():" + mongoDatabase.getName());
                //查找表数据
                //mongoDatabase.getCollection("test").find().iterator();

                if(mongoDatabase != null) {
                    return ReturnT.SUCCESS;
                } else {
                    return ReturnT.FAIL;
                }
            } catch (Exception e) {
                return ReturnT.FAIL;
            } finally {
                // 关闭数据库连接
                if(mongoClient != null) {
                    mongoClient.close();
                }
            }
        } else {
            Connection con = null;
            try {
                DriverManagerDataSource dataSource = new DriverManagerDataSource();
                dataSource.setDriverClassName(dbInfo.getDbDriver());
                dataSource.setUrl(dbInfo.getDbUrl());
                dataSource.setUsername(dbInfo.getDbUserName());
                dataSource.setPassword(dbInfo.getDbPassword());
                JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
                con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
                if (null != con) {
                    return ReturnT.SUCCESS;
                } else {
                    return ReturnT.FAIL;
                }
            } catch (Exception e) {
                return ReturnT.FAIL;
            } finally {
                if(null != con) {
                    try {
                        con.close();
                        System.out.println("链接关闭成功！");
                    } catch (Exception e) {
                        return ReturnT.FAIL;
                    }

                }
            }

        }
    }

    /**
     * test new dbInfo
     *
     * @param dbInfo
     * @return
     */
    @Override
    public ReturnT<String> testNewDbInfo(DbInfo dbInfo) {
        if(dbInfo == null) return ReturnT.FAIL;

        if(StringUtils.isNotBlank(dbInfo.getDbType()) && Constants.DB_TYPE_MONGODB.equals(dbInfo.getDbType())) {
            MongoClient mongoClient = null;
            try {
                //MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(new MongoClient(dbInfo.getDbUrl(), Integer.parseInt(dbInfo.getMongodbPort())), dbInfo.getMongodbDatabase());
                ServerAddress serverAddress = new ServerAddress(dbInfo.getDbUrl(),Integer.parseInt(dbInfo.getMongodbPort()));
                List<ServerAddress> addrs = new ArrayList<>();
                addrs.add(serverAddress);
                //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
                MongoCredential credential = MongoCredential.createScramSha1Credential(dbInfo.getDbUserName(), dbInfo.getMongodbDatabase(), dbInfo.getDbPassword().toCharArray());
                List<MongoCredential> credentials = new ArrayList<>();
                credentials.add(credential);
                //通过连接认证获取MongoDB连接
                mongoClient = new MongoClient(addrs,credentials);
                //连接到数据库
                MongoDatabase mongoDatabase = mongoClient.getDatabase(dbInfo.getMongodbDatabase());
                System.out.println("mongoDatabase.getName():" + mongoDatabase.getName());
                //查找表数据
                //mongoDatabase.getCollection("test").find().iterator();

                if(mongoDatabase != null) {
                    return ReturnT.SUCCESS;
                } else {
                    return ReturnT.FAIL;
                }
            } catch (Exception e) {
                return ReturnT.FAIL;
            } finally {
                if(mongoClient != null) {
                    mongoClient.close();
                }
            }
        } else {
            Connection con = null;
            try {
                DriverManagerDataSource dataSource = new DriverManagerDataSource();
                dataSource.setDriverClassName(dbInfo.getDbDriver());
                dataSource.setUrl(dbInfo.getDbUrl());
                dataSource.setUsername(dbInfo.getDbUserName());
                dataSource.setPassword(dbInfo.getDbPassword());
                JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
                con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
                if (null != con) {
                    return ReturnT.SUCCESS;
                } else {
                    return ReturnT.FAIL;
                }
            } catch (Exception e) {
                return ReturnT.FAIL;
            } finally {
                if(null != con) {
                    try {
                        con.close();
                    } catch (Exception e) {
                        return ReturnT.FAIL;
                    }

                }
            }

        }
    }


}
